We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add `socket_options` to `httpx.HTTPTransport`.
Since [version 0.17.2](https://github.com/encode/httpcore/pull/697#issuecomment-1559059612) the `httpcore` package has support for a `socket_options` parameter.
We should add a corresponding parameter to `httpx.HTTPTransport`, which can be passed through to the connection pool.

This will resolve the use-case raised in discussion https://github.com/encode/httpx/discussions/2635...

```python
>>> import httpx
>>> socket_options = [(socket.SOL_SOCKET, socket.SO_BINDTODEVICE, b"ETH999")]
>>> transport = httpx.HTTPTransport(socket_options=socket_options)
>>> client = httpx.Client(transport=transport)
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `httpx/_transports/default.py`
Content:
```
1 """
2 Custom transports, with nicely configured defaults.
3 
4 The following additional keyword arguments are currently supported by httpcore...
5 
6 * uds: str
7 * local_address: str
8 * retries: int
9 
10 Example usages...
11 
12 # Disable HTTP/2 on a single specific domain.
13 mounts = {
14     "all://": httpx.HTTPTransport(http2=True),
15     "all://*example.org": httpx.HTTPTransport()
16 }
17 
18 # Using advanced httpcore configuration, with connection retries.
19 transport = httpx.HTTPTransport(retries=1)
20 client = httpx.Client(transport=transport)
21 
22 # Using advanced httpcore configuration, with unix domain sockets.
23 transport = httpx.HTTPTransport(uds="socket.uds")
24 client = httpx.Client(transport=transport)
25 """
26 import contextlib
27 import typing
28 from types import TracebackType
29 
30 import httpcore
31 
32 from .._config import DEFAULT_LIMITS, Limits, Proxy, create_ssl_context
33 from .._exceptions import (
34     ConnectError,
35     ConnectTimeout,
36     LocalProtocolError,
37     NetworkError,
38     PoolTimeout,
39     ProtocolError,
40     ProxyError,
41     ReadError,
42     ReadTimeout,
43     RemoteProtocolError,
44     TimeoutException,
45     UnsupportedProtocol,
46     WriteError,
47     WriteTimeout,
48 )
49 from .._models import Request, Response
50 from .._types import AsyncByteStream, CertTypes, SyncByteStream, VerifyTypes
51 from .base import AsyncBaseTransport, BaseTransport
52 
53 T = typing.TypeVar("T", bound="HTTPTransport")
54 A = typing.TypeVar("A", bound="AsyncHTTPTransport")
55 
56 
57 @contextlib.contextmanager
58 def map_httpcore_exceptions() -> typing.Iterator[None]:
59     try:
60         yield
61     except Exception as exc:  # noqa: PIE-786
62         mapped_exc = None
63 
64         for from_exc, to_exc in HTTPCORE_EXC_MAP.items():
65             if not isinstance(exc, from_exc):
66                 continue
67             # We want to map to the most specific exception we can find.
68             # Eg if `exc` is an `httpcore.ReadTimeout`, we want to map to
69             # `httpx.ReadTimeout`, not just `httpx.TimeoutException`.
70             if mapped_exc is None or issubclass(to_exc, mapped_exc):
71                 mapped_exc = to_exc
72 
73         if mapped_exc is None:  # pragma: no cover
74             raise
75 
76         message = str(exc)
77         raise mapped_exc(message) from exc
78 
79 
80 HTTPCORE_EXC_MAP = {
81     httpcore.TimeoutException: TimeoutException,
82     httpcore.ConnectTimeout: ConnectTimeout,
83     httpcore.ReadTimeout: ReadTimeout,
84     httpcore.WriteTimeout: WriteTimeout,
85     httpcore.PoolTimeout: PoolTimeout,
86     httpcore.NetworkError: NetworkError,
87     httpcore.ConnectError: ConnectError,
88     httpcore.ReadError: ReadError,
89     httpcore.WriteError: WriteError,
90     httpcore.ProxyError: ProxyError,
91     httpcore.UnsupportedProtocol: UnsupportedProtocol,
92     httpcore.ProtocolError: ProtocolError,
93     httpcore.LocalProtocolError: LocalProtocolError,
94     httpcore.RemoteProtocolError: RemoteProtocolError,
95 }
96 
97 
98 class ResponseStream(SyncByteStream):
99     def __init__(self, httpcore_stream: typing.Iterable[bytes]):
100         self._httpcore_stream = httpcore_stream
101 
102     def __iter__(self) -> typing.Iterator[bytes]:
103         with map_httpcore_exceptions():
104             for part in self._httpcore_stream:
105                 yield part
106 
107     def close(self) -> None:
108         if hasattr(self._httpcore_stream, "close"):
109             self._httpcore_stream.close()
110 
111 
112 class HTTPTransport(BaseTransport):
113     def __init__(
114         self,
115         verify: VerifyTypes = True,
116         cert: typing.Optional[CertTypes] = None,
117         http1: bool = True,
118         http2: bool = False,
119         limits: Limits = DEFAULT_LIMITS,
120         trust_env: bool = True,
121         proxy: typing.Optional[Proxy] = None,
122         uds: typing.Optional[str] = None,
123         local_address: typing.Optional[str] = None,
124         retries: int = 0,
125     ) -> None:
126         ssl_context = create_ssl_context(verify=verify, cert=cert, trust_env=trust_env)
127 
128         if proxy is None:
129             self._pool = httpcore.ConnectionPool(
130                 ssl_context=ssl_context,
131                 max_connections=limits.max_connections,
132                 max_keepalive_connections=limits.max_keepalive_connections,
133                 keepalive_expiry=limits.keepalive_expiry,
134                 http1=http1,
135                 http2=http2,
136                 uds=uds,
137                 local_address=local_address,
138                 retries=retries,
139             )
140         elif proxy.url.scheme in ("http", "https"):
141             self._pool = httpcore.HTTPProxy(
142                 proxy_url=httpcore.URL(
143                     scheme=proxy.url.raw_scheme,
144                     host=proxy.url.raw_host,
145                     port=proxy.url.port,
146                     target=proxy.url.raw_path,
147                 ),
148                 proxy_auth=proxy.raw_auth,
149                 proxy_headers=proxy.headers.raw,
150                 ssl_context=ssl_context,
151                 max_connections=limits.max_connections,
152                 max_keepalive_connections=limits.max_keepalive_connections,
153                 keepalive_expiry=limits.keepalive_expiry,
154                 http1=http1,
155                 http2=http2,
156             )
157         elif proxy.url.scheme == "socks5":
158             try:
159                 import socksio  # noqa
160             except ImportError:  # pragma: no cover
161                 raise ImportError(
162                     "Using SOCKS proxy, but the 'socksio' package is not installed. "
163                     "Make sure to install httpx using `pip install httpx[socks]`."
164                 ) from None
165 
166             self._pool = httpcore.SOCKSProxy(
167                 proxy_url=httpcore.URL(
168                     scheme=proxy.url.raw_scheme,
169                     host=proxy.url.raw_host,
170                     port=proxy.url.port,
171                     target=proxy.url.raw_path,
172                 ),
173                 proxy_auth=proxy.raw_auth,
174                 ssl_context=ssl_context,
175                 max_connections=limits.max_connections,
176                 max_keepalive_connections=limits.max_keepalive_connections,
177                 keepalive_expiry=limits.keepalive_expiry,
178                 http1=http1,
179                 http2=http2,
180             )
181         else:  # pragma: no cover
182             raise ValueError(
183                 f"Proxy protocol must be either 'http', 'https', or 'socks5', but got {proxy.url.scheme!r}."
184             )
185 
186     def __enter__(self: T) -> T:  # Use generics for subclass support.
187         self._pool.__enter__()
188         return self
189 
190     def __exit__(
191         self,
192         exc_type: typing.Optional[typing.Type[BaseException]] = None,
193         exc_value: typing.Optional[BaseException] = None,
194         traceback: typing.Optional[TracebackType] = None,
195     ) -> None:
196         with map_httpcore_exceptions():
197             self._pool.__exit__(exc_type, exc_value, traceback)
198 
199     def handle_request(
200         self,
201         request: Request,
202     ) -> Response:
203         assert isinstance(request.stream, SyncByteStream)
204 
205         req = httpcore.Request(
206             method=request.method,
207             url=httpcore.URL(
208                 scheme=request.url.raw_scheme,
209                 host=request.url.raw_host,
210                 port=request.url.port,
211                 target=request.url.raw_path,
212             ),
213             headers=request.headers.raw,
214             content=request.stream,
215             extensions=request.extensions,
216         )
217         with map_httpcore_exceptions():
218             resp = self._pool.handle_request(req)
219 
220         assert isinstance(resp.stream, typing.Iterable)
221 
222         return Response(
223             status_code=resp.status,
224             headers=resp.headers,
225             stream=ResponseStream(resp.stream),
226             extensions=resp.extensions,
227         )
228 
229     def close(self) -> None:
230         self._pool.close()
231 
232 
233 class AsyncResponseStream(AsyncByteStream):
234     def __init__(self, httpcore_stream: typing.AsyncIterable[bytes]):
235         self._httpcore_stream = httpcore_stream
236 
237     async def __aiter__(self) -> typing.AsyncIterator[bytes]:
238         with map_httpcore_exceptions():
239             async for part in self._httpcore_stream:
240                 yield part
241 
242     async def aclose(self) -> None:
243         if hasattr(self._httpcore_stream, "aclose"):
244             await self._httpcore_stream.aclose()
245 
246 
247 class AsyncHTTPTransport(AsyncBaseTransport):
248     def __init__(
249         self,
250         verify: VerifyTypes = True,
251         cert: typing.Optional[CertTypes] = None,
252         http1: bool = True,
253         http2: bool = False,
254         limits: Limits = DEFAULT_LIMITS,
255         trust_env: bool = True,
256         proxy: typing.Optional[Proxy] = None,
257         uds: typing.Optional[str] = None,
258         local_address: typing.Optional[str] = None,
259         retries: int = 0,
260     ) -> None:
261         ssl_context = create_ssl_context(verify=verify, cert=cert, trust_env=trust_env)
262 
263         if proxy is None:
264             self._pool = httpcore.AsyncConnectionPool(
265                 ssl_context=ssl_context,
266                 max_connections=limits.max_connections,
267                 max_keepalive_connections=limits.max_keepalive_connections,
268                 keepalive_expiry=limits.keepalive_expiry,
269                 http1=http1,
270                 http2=http2,
271                 uds=uds,
272                 local_address=local_address,
273                 retries=retries,
274             )
275         elif proxy.url.scheme in ("http", "https"):
276             self._pool = httpcore.AsyncHTTPProxy(
277                 proxy_url=httpcore.URL(
278                     scheme=proxy.url.raw_scheme,
279                     host=proxy.url.raw_host,
280                     port=proxy.url.port,
281                     target=proxy.url.raw_path,
282                 ),
283                 proxy_auth=proxy.raw_auth,
284                 proxy_headers=proxy.headers.raw,
285                 ssl_context=ssl_context,
286                 max_connections=limits.max_connections,
287                 max_keepalive_connections=limits.max_keepalive_connections,
288                 keepalive_expiry=limits.keepalive_expiry,
289                 http1=http1,
290                 http2=http2,
291             )
292         elif proxy.url.scheme == "socks5":
293             try:
294                 import socksio  # noqa
295             except ImportError:  # pragma: no cover
296                 raise ImportError(
297                     "Using SOCKS proxy, but the 'socksio' package is not installed. "
298                     "Make sure to install httpx using `pip install httpx[socks]`."
299                 ) from None
300 
301             self._pool = httpcore.AsyncSOCKSProxy(
302                 proxy_url=httpcore.URL(
303                     scheme=proxy.url.raw_scheme,
304                     host=proxy.url.raw_host,
305                     port=proxy.url.port,
306                     target=proxy.url.raw_path,
307                 ),
308                 proxy_auth=proxy.raw_auth,
309                 ssl_context=ssl_context,
310                 max_connections=limits.max_connections,
311                 max_keepalive_connections=limits.max_keepalive_connections,
312                 keepalive_expiry=limits.keepalive_expiry,
313                 http1=http1,
314                 http2=http2,
315             )
316         else:  # pragma: no cover
317             raise ValueError(
318                 f"Proxy protocol must be either 'http', 'https', or 'socks5', but got {proxy.url.scheme!r}."
319             )
320 
321     async def __aenter__(self: A) -> A:  # Use generics for subclass support.
322         await self._pool.__aenter__()
323         return self
324 
325     async def __aexit__(
326         self,
327         exc_type: typing.Optional[typing.Type[BaseException]] = None,
328         exc_value: typing.Optional[BaseException] = None,
329         traceback: typing.Optional[TracebackType] = None,
330     ) -> None:
331         with map_httpcore_exceptions():
332             await self._pool.__aexit__(exc_type, exc_value, traceback)
333 
334     async def handle_async_request(
335         self,
336         request: Request,
337     ) -> Response:
338         assert isinstance(request.stream, AsyncByteStream)
339 
340         req = httpcore.Request(
341             method=request.method,
342             url=httpcore.URL(
343                 scheme=request.url.raw_scheme,
344                 host=request.url.raw_host,
345                 port=request.url.port,
346                 target=request.url.raw_path,
347             ),
348             headers=request.headers.raw,
349             content=request.stream,
350             extensions=request.extensions,
351         )
352         with map_httpcore_exceptions():
353             resp = await self._pool.handle_async_request(req)
354 
355         assert isinstance(resp.stream, typing.AsyncIterable)
356 
357         return Response(
358             status_code=resp.status,
359             headers=resp.headers,
360             stream=AsyncResponseStream(resp.stream),
361             extensions=resp.extensions,
362         )
363 
364     async def aclose(self) -> None:
365         await self._pool.aclose()
366
```
--- 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/httpx/_transports/default.py b/httpx/_transports/default.py
--- a/httpx/_transports/default.py
+++ b/httpx/_transports/default.py
@@ -53,6 +53,12 @@
 T = typing.TypeVar("T", bound="HTTPTransport")
 A = typing.TypeVar("A", bound="AsyncHTTPTransport")
 
+SOCKET_OPTION = typing.Union[
+    typing.Tuple[int, int, int],
+    typing.Tuple[int, int, typing.Union[bytes, bytearray]],
+    typing.Tuple[int, int, None, int],
+]
+
 
 @contextlib.contextmanager
 def map_httpcore_exceptions() -> typing.Iterator[None]:
@@ -122,6 +128,7 @@
         uds: typing.Optional[str] = None,
         local_address: typing.Optional[str] = None,
         retries: int = 0,
+        socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None,
     ) -> None:
         ssl_context = create_ssl_context(verify=verify, cert=cert, trust_env=trust_env)
 
@@ -136,6 +143,7 @@
                 uds=uds,
                 local_address=local_address,
                 retries=retries,
+                socket_options=socket_options,
             )
         elif proxy.url.scheme in ("http", "https"):
             self._pool = httpcore.HTTPProxy(
@@ -153,6 +161,7 @@
                 keepalive_expiry=limits.keepalive_expiry,
                 http1=http1,
                 http2=http2,
+                socket_options=socket_options,
             )
         elif proxy.url.scheme == "socks5":
             try:
@@ -257,6 +266,7 @@
         uds: typing.Optional[str] = None,
         local_address: typing.Optional[str] = None,
         retries: int = 0,
+        socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None,
     ) -> None:
         ssl_context = create_ssl_context(verify=verify, cert=cert, trust_env=trust_env)
 
@@ -271,6 +281,7 @@
                 uds=uds,
                 local_address=local_address,
                 retries=retries,
+                socket_options=socket_options,
             )
         elif proxy.url.scheme in ("http", "https"):
             self._pool = httpcore.AsyncHTTPProxy(
@@ -288,6 +299,7 @@
                 keepalive_expiry=limits.keepalive_expiry,
                 http1=http1,
                 http2=http2,
+                socket_options=socket_options,
             )
         elif proxy.url.scheme == "socks5":
             try:

{"golden_diff": "diff --git a/httpx/_transports/default.py b/httpx/_transports/default.py\n--- a/httpx/_transports/default.py\n+++ b/httpx/_transports/default.py\n@@ -53,6 +53,12 @@\n T = typing.TypeVar(\"T\", bound=\"HTTPTransport\")\n A = typing.TypeVar(\"A\", bound=\"AsyncHTTPTransport\")\n \n+SOCKET_OPTION = typing.Union[\n+    typing.Tuple[int, int, int],\n+    typing.Tuple[int, int, typing.Union[bytes, bytearray]],\n+    typing.Tuple[int, int, None, int],\n+]\n+\n \n @contextlib.contextmanager\n def map_httpcore_exceptions() -> typing.Iterator[None]:\n@@ -122,6 +128,7 @@\n         uds: typing.Optional[str] = None,\n         local_address: typing.Optional[str] = None,\n         retries: int = 0,\n+        socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None,\n     ) -> None:\n         ssl_context = create_ssl_context(verify=verify, cert=cert, trust_env=trust_env)\n \n@@ -136,6 +143,7 @@\n                 uds=uds,\n                 local_address=local_address,\n                 retries=retries,\n+                socket_options=socket_options,\n             )\n         elif proxy.url.scheme in (\"http\", \"https\"):\n             self._pool = httpcore.HTTPProxy(\n@@ -153,6 +161,7 @@\n                 keepalive_expiry=limits.keepalive_expiry,\n                 http1=http1,\n                 http2=http2,\n+                socket_options=socket_options,\n             )\n         elif proxy.url.scheme == \"socks5\":\n             try:\n@@ -257,6 +266,7 @@\n         uds: typing.Optional[str] = None,\n         local_address: typing.Optional[str] = None,\n         retries: int = 0,\n+        socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None,\n     ) -> None:\n         ssl_context = create_ssl_context(verify=verify, cert=cert, trust_env=trust_env)\n \n@@ -271,6 +281,7 @@\n                 uds=uds,\n                 local_address=local_address,\n                 retries=retries,\n+                socket_options=socket_options,\n             )\n         elif proxy.url.scheme in (\"http\", \"https\"):\n             self._pool = httpcore.AsyncHTTPProxy(\n@@ -288,6 +299,7 @@\n                 keepalive_expiry=limits.keepalive_expiry,\n                 http1=http1,\n                 http2=http2,\n+                socket_options=socket_options,\n             )\n         elif proxy.url.scheme == \"socks5\":\n             try:\n", "issue": "Add `socket_options` to `httpx.HTTPTransport`.\nSince [version 0.17.2](https://github.com/encode/httpcore/pull/697#issuecomment-1559059612) the `httpcore` package has support for a `socket_options` parameter.\r\nWe should add a corresponding parameter to `httpx.HTTPTransport`, which can be passed through to the connection pool.\r\n\r\nThis will resolve the use-case raised in discussion https://github.com/encode/httpx/discussions/2635...\r\n\r\n```python\r\n>>> import httpx\r\n>>> socket_options = [(socket.SOL_SOCKET, socket.SO_BINDTODEVICE, b\"ETH999\")]\r\n>>> transport = httpx.HTTPTransport(socket_options=socket_options)\r\n>>> client = httpx.Client(transport=transport)\r\n```\n", "before_files": [{"content": "\"\"\"\nCustom transports, with nicely configured defaults.\n\nThe following additional keyword arguments are currently supported by httpcore...\n\n* uds: str\n* local_address: str\n* retries: int\n\nExample usages...\n\n# Disable HTTP/2 on a single specific domain.\nmounts = {\n    \"all://\": httpx.HTTPTransport(http2=True),\n    \"all://*example.org\": httpx.HTTPTransport()\n}\n\n# Using advanced httpcore configuration, with connection retries.\ntransport = httpx.HTTPTransport(retries=1)\nclient = httpx.Client(transport=transport)\n\n# Using advanced httpcore configuration, with unix domain sockets.\ntransport = httpx.HTTPTransport(uds=\"socket.uds\")\nclient = httpx.Client(transport=transport)\n\"\"\"\nimport contextlib\nimport typing\nfrom types import TracebackType\n\nimport httpcore\n\nfrom .._config import DEFAULT_LIMITS, Limits, Proxy, create_ssl_context\nfrom .._exceptions import (\n    ConnectError,\n    ConnectTimeout,\n    LocalProtocolError,\n    NetworkError,\n    PoolTimeout,\n    ProtocolError,\n    ProxyError,\n    ReadError,\n    ReadTimeout,\n    RemoteProtocolError,\n    TimeoutException,\n    UnsupportedProtocol,\n    WriteError,\n    WriteTimeout,\n)\nfrom .._models import Request, Response\nfrom .._types import AsyncByteStream, CertTypes, SyncByteStream, VerifyTypes\nfrom .base import AsyncBaseTransport, BaseTransport\n\nT = typing.TypeVar(\"T\", bound=\"HTTPTransport\")\nA = typing.TypeVar(\"A\", bound=\"AsyncHTTPTransport\")\n\n\n@contextlib.contextmanager\ndef map_httpcore_exceptions() -> typing.Iterator[None]:\n    try:\n        yield\n    except Exception as exc:  # noqa: PIE-786\n        mapped_exc = None\n\n        for from_exc, to_exc in HTTPCORE_EXC_MAP.items():\n            if not isinstance(exc, from_exc):\n                continue\n            # We want to map to the most specific exception we can find.\n            # Eg if `exc` is an `httpcore.ReadTimeout`, we want to map to\n            # `httpx.ReadTimeout`, not just `httpx.TimeoutException`.\n            if mapped_exc is None or issubclass(to_exc, mapped_exc):\n                mapped_exc = to_exc\n\n        if mapped_exc is None:  # pragma: no cover\n            raise\n\n        message = str(exc)\n        raise mapped_exc(message) from exc\n\n\nHTTPCORE_EXC_MAP = {\n    httpcore.TimeoutException: TimeoutException,\n    httpcore.ConnectTimeout: ConnectTimeout,\n    httpcore.ReadTimeout: ReadTimeout,\n    httpcore.WriteTimeout: WriteTimeout,\n    httpcore.PoolTimeout: PoolTimeout,\n    httpcore.NetworkError: NetworkError,\n    httpcore.ConnectError: ConnectError,\n    httpcore.ReadError: ReadError,\n    httpcore.WriteError: WriteError,\n    httpcore.ProxyError: ProxyError,\n    httpcore.UnsupportedProtocol: UnsupportedProtocol,\n    httpcore.ProtocolError: ProtocolError,\n    httpcore.LocalProtocolError: LocalProtocolError,\n    httpcore.RemoteProtocolError: RemoteProtocolError,\n}\n\n\nclass ResponseStream(SyncByteStream):\n    def __init__(self, httpcore_stream: typing.Iterable[bytes]):\n        self._httpcore_stream = httpcore_stream\n\n    def __iter__(self) -> typing.Iterator[bytes]:\n        with map_httpcore_exceptions():\n            for part in self._httpcore_stream:\n                yield part\n\n    def close(self) -> None:\n        if hasattr(self._httpcore_stream, \"close\"):\n            self._httpcore_stream.close()\n\n\nclass HTTPTransport(BaseTransport):\n    def __init__(\n        self,\n        verify: VerifyTypes = True,\n        cert: typing.Optional[CertTypes] = None,\n        http1: bool = True,\n        http2: bool = False,\n        limits: Limits = DEFAULT_LIMITS,\n        trust_env: bool = True,\n        proxy: typing.Optional[Proxy] = None,\n        uds: typing.Optional[str] = None,\n        local_address: typing.Optional[str] = None,\n        retries: int = 0,\n    ) -> None:\n        ssl_context = create_ssl_context(verify=verify, cert=cert, trust_env=trust_env)\n\n        if proxy is None:\n            self._pool = httpcore.ConnectionPool(\n                ssl_context=ssl_context,\n                max_connections=limits.max_connections,\n                max_keepalive_connections=limits.max_keepalive_connections,\n                keepalive_expiry=limits.keepalive_expiry,\n                http1=http1,\n                http2=http2,\n                uds=uds,\n                local_address=local_address,\n                retries=retries,\n            )\n        elif proxy.url.scheme in (\"http\", \"https\"):\n            self._pool = httpcore.HTTPProxy(\n                proxy_url=httpcore.URL(\n                    scheme=proxy.url.raw_scheme,\n                    host=proxy.url.raw_host,\n                    port=proxy.url.port,\n                    target=proxy.url.raw_path,\n                ),\n                proxy_auth=proxy.raw_auth,\n                proxy_headers=proxy.headers.raw,\n                ssl_context=ssl_context,\n                max_connections=limits.max_connections,\n                max_keepalive_connections=limits.max_keepalive_connections,\n                keepalive_expiry=limits.keepalive_expiry,\n                http1=http1,\n                http2=http2,\n            )\n        elif proxy.url.scheme == \"socks5\":\n            try:\n                import socksio  # noqa\n            except ImportError:  # pragma: no cover\n                raise ImportError(\n                    \"Using SOCKS proxy, but the 'socksio' package is not installed. \"\n                    \"Make sure to install httpx using `pip install httpx[socks]`.\"\n                ) from None\n\n            self._pool = httpcore.SOCKSProxy(\n                proxy_url=httpcore.URL(\n                    scheme=proxy.url.raw_scheme,\n                    host=proxy.url.raw_host,\n                    port=proxy.url.port,\n                    target=proxy.url.raw_path,\n                ),\n                proxy_auth=proxy.raw_auth,\n                ssl_context=ssl_context,\n                max_connections=limits.max_connections,\n                max_keepalive_connections=limits.max_keepalive_connections,\n                keepalive_expiry=limits.keepalive_expiry,\n                http1=http1,\n                http2=http2,\n            )\n        else:  # pragma: no cover\n            raise ValueError(\n                f\"Proxy protocol must be either 'http', 'https', or 'socks5', but got {proxy.url.scheme!r}.\"\n            )\n\n    def __enter__(self: T) -> T:  # Use generics for subclass support.\n        self._pool.__enter__()\n        return self\n\n    def __exit__(\n        self,\n        exc_type: typing.Optional[typing.Type[BaseException]] = None,\n        exc_value: typing.Optional[BaseException] = None,\n        traceback: typing.Optional[TracebackType] = None,\n    ) -> None:\n        with map_httpcore_exceptions():\n            self._pool.__exit__(exc_type, exc_value, traceback)\n\n    def handle_request(\n        self,\n        request: Request,\n    ) -> Response:\n        assert isinstance(request.stream, SyncByteStream)\n\n        req = httpcore.Request(\n            method=request.method,\n            url=httpcore.URL(\n                scheme=request.url.raw_scheme,\n                host=request.url.raw_host,\n                port=request.url.port,\n                target=request.url.raw_path,\n            ),\n            headers=request.headers.raw,\n            content=request.stream,\n            extensions=request.extensions,\n        )\n        with map_httpcore_exceptions():\n            resp = self._pool.handle_request(req)\n\n        assert isinstance(resp.stream, typing.Iterable)\n\n        return Response(\n            status_code=resp.status,\n            headers=resp.headers,\n            stream=ResponseStream(resp.stream),\n            extensions=resp.extensions,\n        )\n\n    def close(self) -> None:\n        self._pool.close()\n\n\nclass AsyncResponseStream(AsyncByteStream):\n    def __init__(self, httpcore_stream: typing.AsyncIterable[bytes]):\n        self._httpcore_stream = httpcore_stream\n\n    async def __aiter__(self) -> typing.AsyncIterator[bytes]:\n        with map_httpcore_exceptions():\n            async for part in self._httpcore_stream:\n                yield part\n\n    async def aclose(self) -> None:\n        if hasattr(self._httpcore_stream, \"aclose\"):\n            await self._httpcore_stream.aclose()\n\n\nclass AsyncHTTPTransport(AsyncBaseTransport):\n    def __init__(\n        self,\n        verify: VerifyTypes = True,\n        cert: typing.Optional[CertTypes] = None,\n        http1: bool = True,\n        http2: bool = False,\n        limits: Limits = DEFAULT_LIMITS,\n        trust_env: bool = True,\n        proxy: typing.Optional[Proxy] = None,\n        uds: typing.Optional[str] = None,\n        local_address: typing.Optional[str] = None,\n        retries: int = 0,\n    ) -> None:\n        ssl_context = create_ssl_context(verify=verify, cert=cert, trust_env=trust_env)\n\n        if proxy is None:\n            self._pool = httpcore.AsyncConnectionPool(\n                ssl_context=ssl_context,\n                max_connections=limits.max_connections,\n                max_keepalive_connections=limits.max_keepalive_connections,\n                keepalive_expiry=limits.keepalive_expiry,\n                http1=http1,\n                http2=http2,\n                uds=uds,\n                local_address=local_address,\n                retries=retries,\n            )\n        elif proxy.url.scheme in (\"http\", \"https\"):\n            self._pool = httpcore.AsyncHTTPProxy(\n                proxy_url=httpcore.URL(\n                    scheme=proxy.url.raw_scheme,\n                    host=proxy.url.raw_host,\n                    port=proxy.url.port,\n                    target=proxy.url.raw_path,\n                ),\n                proxy_auth=proxy.raw_auth,\n                proxy_headers=proxy.headers.raw,\n                ssl_context=ssl_context,\n                max_connections=limits.max_connections,\n                max_keepalive_connections=limits.max_keepalive_connections,\n                keepalive_expiry=limits.keepalive_expiry,\n                http1=http1,\n                http2=http2,\n            )\n        elif proxy.url.scheme == \"socks5\":\n            try:\n                import socksio  # noqa\n            except ImportError:  # pragma: no cover\n                raise ImportError(\n                    \"Using SOCKS proxy, but the 'socksio' package is not installed. \"\n                    \"Make sure to install httpx using `pip install httpx[socks]`.\"\n                ) from None\n\n            self._pool = httpcore.AsyncSOCKSProxy(\n                proxy_url=httpcore.URL(\n                    scheme=proxy.url.raw_scheme,\n                    host=proxy.url.raw_host,\n                    port=proxy.url.port,\n                    target=proxy.url.raw_path,\n                ),\n                proxy_auth=proxy.raw_auth,\n                ssl_context=ssl_context,\n                max_connections=limits.max_connections,\n                max_keepalive_connections=limits.max_keepalive_connections,\n                keepalive_expiry=limits.keepalive_expiry,\n                http1=http1,\n                http2=http2,\n            )\n        else:  # pragma: no cover\n            raise ValueError(\n                f\"Proxy protocol must be either 'http', 'https', or 'socks5', but got {proxy.url.scheme!r}.\"\n            )\n\n    async def __aenter__(self: A) -> A:  # Use generics for subclass support.\n        await self._pool.__aenter__()\n        return self\n\n    async def __aexit__(\n        self,\n        exc_type: typing.Optional[typing.Type[BaseException]] = None,\n        exc_value: typing.Optional[BaseException] = None,\n        traceback: typing.Optional[TracebackType] = None,\n    ) -> None:\n        with map_httpcore_exceptions():\n            await self._pool.__aexit__(exc_type, exc_value, traceback)\n\n    async def handle_async_request(\n        self,\n        request: Request,\n    ) -> Response:\n        assert isinstance(request.stream, AsyncByteStream)\n\n        req = httpcore.Request(\n            method=request.method,\n            url=httpcore.URL(\n                scheme=request.url.raw_scheme,\n                host=request.url.raw_host,\n                port=request.url.port,\n                target=request.url.raw_path,\n            ),\n            headers=request.headers.raw,\n            content=request.stream,\n            extensions=request.extensions,\n        )\n        with map_httpcore_exceptions():\n            resp = await self._pool.handle_async_request(req)\n\n        assert isinstance(resp.stream, typing.AsyncIterable)\n\n        return Response(\n            status_code=resp.status,\n            headers=resp.headers,\n            stream=AsyncResponseStream(resp.stream),\n            extensions=resp.extensions,\n        )\n\n    async def aclose(self) -> None:\n        await self._pool.aclose()\n", "path": "httpx/_transports/default.py"}], "after_files": [{"content": "\"\"\"\nCustom transports, with nicely configured defaults.\n\nThe following additional keyword arguments are currently supported by httpcore...\n\n* uds: str\n* local_address: str\n* retries: int\n\nExample usages...\n\n# Disable HTTP/2 on a single specific domain.\nmounts = {\n    \"all://\": httpx.HTTPTransport(http2=True),\n    \"all://*example.org\": httpx.HTTPTransport()\n}\n\n# Using advanced httpcore configuration, with connection retries.\ntransport = httpx.HTTPTransport(retries=1)\nclient = httpx.Client(transport=transport)\n\n# Using advanced httpcore configuration, with unix domain sockets.\ntransport = httpx.HTTPTransport(uds=\"socket.uds\")\nclient = httpx.Client(transport=transport)\n\"\"\"\nimport contextlib\nimport typing\nfrom types import TracebackType\n\nimport httpcore\n\nfrom .._config import DEFAULT_LIMITS, Limits, Proxy, create_ssl_context\nfrom .._exceptions import (\n    ConnectError,\n    ConnectTimeout,\n    LocalProtocolError,\n    NetworkError,\n    PoolTimeout,\n    ProtocolError,\n    ProxyError,\n    ReadError,\n    ReadTimeout,\n    RemoteProtocolError,\n    TimeoutException,\n    UnsupportedProtocol,\n    WriteError,\n    WriteTimeout,\n)\nfrom .._models import Request, Response\nfrom .._types import AsyncByteStream, CertTypes, SyncByteStream, VerifyTypes\nfrom .base import AsyncBaseTransport, BaseTransport\n\nT = typing.TypeVar(\"T\", bound=\"HTTPTransport\")\nA = typing.TypeVar(\"A\", bound=\"AsyncHTTPTransport\")\n\nSOCKET_OPTION = typing.Union[\n    typing.Tuple[int, int, int],\n    typing.Tuple[int, int, typing.Union[bytes, bytearray]],\n    typing.Tuple[int, int, None, int],\n]\n\n\n@contextlib.contextmanager\ndef map_httpcore_exceptions() -> typing.Iterator[None]:\n    try:\n        yield\n    except Exception as exc:  # noqa: PIE-786\n        mapped_exc = None\n\n        for from_exc, to_exc in HTTPCORE_EXC_MAP.items():\n            if not isinstance(exc, from_exc):\n                continue\n            # We want to map to the most specific exception we can find.\n            # Eg if `exc` is an `httpcore.ReadTimeout`, we want to map to\n            # `httpx.ReadTimeout`, not just `httpx.TimeoutException`.\n            if mapped_exc is None or issubclass(to_exc, mapped_exc):\n                mapped_exc = to_exc\n\n        if mapped_exc is None:  # pragma: no cover\n            raise\n\n        message = str(exc)\n        raise mapped_exc(message) from exc\n\n\nHTTPCORE_EXC_MAP = {\n    httpcore.TimeoutException: TimeoutException,\n    httpcore.ConnectTimeout: ConnectTimeout,\n    httpcore.ReadTimeout: ReadTimeout,\n    httpcore.WriteTimeout: WriteTimeout,\n    httpcore.PoolTimeout: PoolTimeout,\n    httpcore.NetworkError: NetworkError,\n    httpcore.ConnectError: ConnectError,\n    httpcore.ReadError: ReadError,\n    httpcore.WriteError: WriteError,\n    httpcore.ProxyError: ProxyError,\n    httpcore.UnsupportedProtocol: UnsupportedProtocol,\n    httpcore.ProtocolError: ProtocolError,\n    httpcore.LocalProtocolError: LocalProtocolError,\n    httpcore.RemoteProtocolError: RemoteProtocolError,\n}\n\n\nclass ResponseStream(SyncByteStream):\n    def __init__(self, httpcore_stream: typing.Iterable[bytes]):\n        self._httpcore_stream = httpcore_stream\n\n    def __iter__(self) -> typing.Iterator[bytes]:\n        with map_httpcore_exceptions():\n            for part in self._httpcore_stream:\n                yield part\n\n    def close(self) -> None:\n        if hasattr(self._httpcore_stream, \"close\"):\n            self._httpcore_stream.close()\n\n\nclass HTTPTransport(BaseTransport):\n    def __init__(\n        self,\n        verify: VerifyTypes = True,\n        cert: typing.Optional[CertTypes] = None,\n        http1: bool = True,\n        http2: bool = False,\n        limits: Limits = DEFAULT_LIMITS,\n        trust_env: bool = True,\n        proxy: typing.Optional[Proxy] = None,\n        uds: typing.Optional[str] = None,\n        local_address: typing.Optional[str] = None,\n        retries: int = 0,\n        socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None,\n    ) -> None:\n        ssl_context = create_ssl_context(verify=verify, cert=cert, trust_env=trust_env)\n\n        if proxy is None:\n            self._pool = httpcore.ConnectionPool(\n                ssl_context=ssl_context,\n                max_connections=limits.max_connections,\n                max_keepalive_connections=limits.max_keepalive_connections,\n                keepalive_expiry=limits.keepalive_expiry,\n                http1=http1,\n                http2=http2,\n                uds=uds,\n                local_address=local_address,\n                retries=retries,\n                socket_options=socket_options,\n            )\n        elif proxy.url.scheme in (\"http\", \"https\"):\n            self._pool = httpcore.HTTPProxy(\n                proxy_url=httpcore.URL(\n                    scheme=proxy.url.raw_scheme,\n                    host=proxy.url.raw_host,\n                    port=proxy.url.port,\n                    target=proxy.url.raw_path,\n                ),\n                proxy_auth=proxy.raw_auth,\n                proxy_headers=proxy.headers.raw,\n                ssl_context=ssl_context,\n                max_connections=limits.max_connections,\n                max_keepalive_connections=limits.max_keepalive_connections,\n                keepalive_expiry=limits.keepalive_expiry,\n                http1=http1,\n                http2=http2,\n                socket_options=socket_options,\n            )\n        elif proxy.url.scheme == \"socks5\":\n            try:\n                import socksio  # noqa\n            except ImportError:  # pragma: no cover\n                raise ImportError(\n                    \"Using SOCKS proxy, but the 'socksio' package is not installed. \"\n                    \"Make sure to install httpx using `pip install httpx[socks]`.\"\n                ) from None\n\n            self._pool = httpcore.SOCKSProxy(\n                proxy_url=httpcore.URL(\n                    scheme=proxy.url.raw_scheme,\n                    host=proxy.url.raw_host,\n                    port=proxy.url.port,\n                    target=proxy.url.raw_path,\n                ),\n                proxy_auth=proxy.raw_auth,\n                ssl_context=ssl_context,\n                max_connections=limits.max_connections,\n                max_keepalive_connections=limits.max_keepalive_connections,\n                keepalive_expiry=limits.keepalive_expiry,\n                http1=http1,\n                http2=http2,\n            )\n        else:  # pragma: no cover\n            raise ValueError(\n                f\"Proxy protocol must be either 'http', 'https', or 'socks5', but got {proxy.url.scheme!r}.\"\n            )\n\n    def __enter__(self: T) -> T:  # Use generics for subclass support.\n        self._pool.__enter__()\n        return self\n\n    def __exit__(\n        self,\n        exc_type: typing.Optional[typing.Type[BaseException]] = None,\n        exc_value: typing.Optional[BaseException] = None,\n        traceback: typing.Optional[TracebackType] = None,\n    ) -> None:\n        with map_httpcore_exceptions():\n            self._pool.__exit__(exc_type, exc_value, traceback)\n\n    def handle_request(\n        self,\n        request: Request,\n    ) -> Response:\n        assert isinstance(request.stream, SyncByteStream)\n\n        req = httpcore.Request(\n            method=request.method,\n            url=httpcore.URL(\n                scheme=request.url.raw_scheme,\n                host=request.url.raw_host,\n                port=request.url.port,\n                target=request.url.raw_path,\n            ),\n            headers=request.headers.raw,\n            content=request.stream,\n            extensions=request.extensions,\n        )\n        with map_httpcore_exceptions():\n            resp = self._pool.handle_request(req)\n\n        assert isinstance(resp.stream, typing.Iterable)\n\n        return Response(\n            status_code=resp.status,\n            headers=resp.headers,\n            stream=ResponseStream(resp.stream),\n            extensions=resp.extensions,\n        )\n\n    def close(self) -> None:\n        self._pool.close()\n\n\nclass AsyncResponseStream(AsyncByteStream):\n    def __init__(self, httpcore_stream: typing.AsyncIterable[bytes]):\n        self._httpcore_stream = httpcore_stream\n\n    async def __aiter__(self) -> typing.AsyncIterator[bytes]:\n        with map_httpcore_exceptions():\n            async for part in self._httpcore_stream:\n                yield part\n\n    async def aclose(self) -> None:\n        if hasattr(self._httpcore_stream, \"aclose\"):\n            await self._httpcore_stream.aclose()\n\n\nclass AsyncHTTPTransport(AsyncBaseTransport):\n    def __init__(\n        self,\n        verify: VerifyTypes = True,\n        cert: typing.Optional[CertTypes] = None,\n        http1: bool = True,\n        http2: bool = False,\n        limits: Limits = DEFAULT_LIMITS,\n        trust_env: bool = True,\n        proxy: typing.Optional[Proxy] = None,\n        uds: typing.Optional[str] = None,\n        local_address: typing.Optional[str] = None,\n        retries: int = 0,\n        socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None,\n    ) -> None:\n        ssl_context = create_ssl_context(verify=verify, cert=cert, trust_env=trust_env)\n\n        if proxy is None:\n            self._pool = httpcore.AsyncConnectionPool(\n                ssl_context=ssl_context,\n                max_connections=limits.max_connections,\n                max_keepalive_connections=limits.max_keepalive_connections,\n                keepalive_expiry=limits.keepalive_expiry,\n                http1=http1,\n                http2=http2,\n                uds=uds,\n                local_address=local_address,\n                retries=retries,\n                socket_options=socket_options,\n            )\n        elif proxy.url.scheme in (\"http\", \"https\"):\n            self._pool = httpcore.AsyncHTTPProxy(\n                proxy_url=httpcore.URL(\n                    scheme=proxy.url.raw_scheme,\n                    host=proxy.url.raw_host,\n                    port=proxy.url.port,\n                    target=proxy.url.raw_path,\n                ),\n                proxy_auth=proxy.raw_auth,\n                proxy_headers=proxy.headers.raw,\n                ssl_context=ssl_context,\n                max_connections=limits.max_connections,\n                max_keepalive_connections=limits.max_keepalive_connections,\n                keepalive_expiry=limits.keepalive_expiry,\n                http1=http1,\n                http2=http2,\n                socket_options=socket_options,\n            )\n        elif proxy.url.scheme == \"socks5\":\n            try:\n                import socksio  # noqa\n            except ImportError:  # pragma: no cover\n                raise ImportError(\n                    \"Using SOCKS proxy, but the 'socksio' package is not installed. \"\n                    \"Make sure to install httpx using `pip install httpx[socks]`.\"\n                ) from None\n\n            self._pool = httpcore.AsyncSOCKSProxy(\n                proxy_url=httpcore.URL(\n                    scheme=proxy.url.raw_scheme,\n                    host=proxy.url.raw_host,\n                    port=proxy.url.port,\n                    target=proxy.url.raw_path,\n                ),\n                proxy_auth=proxy.raw_auth,\n                ssl_context=ssl_context,\n                max_connections=limits.max_connections,\n                max_keepalive_connections=limits.max_keepalive_connections,\n                keepalive_expiry=limits.keepalive_expiry,\n                http1=http1,\n                http2=http2,\n            )\n        else:  # pragma: no cover\n            raise ValueError(\n                f\"Proxy protocol must be either 'http', 'https', or 'socks5', but got {proxy.url.scheme!r}.\"\n            )\n\n    async def __aenter__(self: A) -> A:  # Use generics for subclass support.\n        await self._pool.__aenter__()\n        return self\n\n    async def __aexit__(\n        self,\n        exc_type: typing.Optional[typing.Type[BaseException]] = None,\n        exc_value: typing.Optional[BaseException] = None,\n        traceback: typing.Optional[TracebackType] = None,\n    ) -> None:\n        with map_httpcore_exceptions():\n            await self._pool.__aexit__(exc_type, exc_value, traceback)\n\n    async def handle_async_request(\n        self,\n        request: Request,\n    ) -> Response:\n        assert isinstance(request.stream, AsyncByteStream)\n\n        req = httpcore.Request(\n            method=request.method,\n            url=httpcore.URL(\n                scheme=request.url.raw_scheme,\n                host=request.url.raw_host,\n                port=request.url.port,\n                target=request.url.raw_path,\n            ),\n            headers=request.headers.raw,\n            content=request.stream,\n            extensions=request.extensions,\n        )\n        with map_httpcore_exceptions():\n            resp = await self._pool.handle_async_request(req)\n\n        assert isinstance(resp.stream, typing.AsyncIterable)\n\n        return Response(\n            status_code=resp.status,\n            headers=resp.headers,\n            stream=AsyncResponseStream(resp.stream),\n            extensions=resp.extensions,\n        )\n\n    async def aclose(self) -> None:\n        await self._pool.aclose()\n", "path": "httpx/_transports/default.py"}]}