← mined_httpx_oracle2

httpx_3377

failed WRONG_FIX UNSUBMITTED wrong_fix_unsubmitted(None) · None tool calls · 0 s · encode/httpx

Task input

(not found in data/tasks.jsonl)

Tool calls (0)

#ToolArgumentsResult
No trace captured.

Patch

--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,9 +4,9 @@ All notable changes to this project will be documented in this file.
 
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 
-## Version 0.28.0
+## [Unreleased]
 
-Version 0.28.0 introduces an `httpx.SSLContext()` class and `ssl_context` parameter.
+This release introduces an `httpx.SSLContext()` class and `ssl_context` parameter.
 
 * Added `httpx.SSLContext` class and `ssl_context` parameter. (#3022, #3335)
 * The `verify` and `cert` arguments have been deprecated and will now raise warnings. (#3022, #3335)
@@ -15,6 +15,7 @@ Version 0.28.0 introduces an `httpx.SSLContext()` class and `ssl_context` parame
 * The `URL.raw` property has now been removed.
 * Ensure JSON request bodies are compact. (#3363)
 * Review URL percent escape sets, based on WHATWG spec. (#3371, #3373)
+* Ensure `certifi` and `httpcore` are only imported if required. (#3377)
 
 ## 0.27.2 (27th August, 2024)
 
--- a/httpx/__version__.py
+++ b/httpx/__version__.py
@@ -1,3 +1,3 @@
 __title__ = "httpx"
 __description__ = "A next generation HTTP client, for Python 3."
-__version__ = "0.28.0"
+__version__ = "0.27.2"
--- a/httpx/_config.py
+++ b/httpx/_config.py
@@ -6,8 +6,6 @@ import sys
 import typing
 import warnings
 
-import certifi
-
 from ._models import Headers
 from ._types import HeaderTypes, TimeoutTypes
 from ._urls import URL
@@ -77,6 +75,8 @@ class SSLContext(ssl.SSLContext):
         self,
         verify: bool = True,
     ) -> None:
+        import certifi
+
         # ssl.SSLContext sets OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION,
         # OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE and OP_SINGLE_ECDH_USE
         # by default. (from `ssl.create_default_context`)
--- a/httpx/_main.py
+++ b/httpx/_main.py
@@ -6,7 +6,6 @@ import sys
 import typing
 
 import click
-import httpcore
 import pygments.lexers
 import pygments.util
 import rich.console
@@ -21,6 +20,9 @@ from ._exceptions import RequestError
 from ._models import Response
 from ._status_codes import codes
 
+if typing.TYPE_CHECKING:
+    import httpcore  # pragma: no cover
+
 
 def print_help() -> None:
     console = rich.console.Console()
--- a/httpx/_transports/default.py
+++ b/httpx/_transports/default.py
@@ -27,11 +27,13 @@ client = httpx.Client(transport=transport)
 from __future__ import annotations
 
 import contextlib
-import ssl
 import typing
 from types import TracebackType
 
-import httpcore
+if typing.TYPE_CHECKING:
+    import ssl  # pragma: no cover
+
+    import httpx  # pragma: no cover
 
 from .._config import DEFAULT_LIMITS, Limits, Proxy, SSLContext, create_ssl_context
 from .._exceptions import (
@@ -66,9 +68,35 @@ SOCKET_OPTION = typing.Union[
 
 __all__ = ["AsyncHTTPTransport", "HTTPTransport"]
 
+HTTPCORE_EXC_MAP: dict[type[Exception], type[httpx.HTTPError]] = {}
+
+
+def _load_httpcore_exceptions() -> dict[type[Exception], type[httpx.HTTPError]]:
+    import httpcore
+
+    return {
+        httpcore.TimeoutException: TimeoutException,
+        httpcore.ConnectTimeout: ConnectTimeout,
+        httpcore.ReadTimeout: ReadTimeout,
+        httpcore.WriteTimeout: WriteTimeout,
+        httpcore.PoolTimeout: PoolTimeout,
+        httpcore.NetworkError: NetworkError,
+        httpcore.ConnectError: ConnectError,
+        httpcore.ReadError: ReadError,
+        httpcore.WriteError: WriteError,
+        httpcore.ProxyError: ProxyError,
+        httpcore.UnsupportedProtocol: UnsupportedProtocol,
+        httpcore.ProtocolError: ProtocolError,
+        httpcore.LocalProtocolError: LocalProtocolError,
+        httpcore.RemoteProtocolError: RemoteProtocolError,
+    }
+
 
 @contextlib.contextmanager
 def map_httpcore_exceptions() -> typing.Iterator[None]:
+    global HTTPCORE_EXC_MAP
+    if len(HTTPCORE_EXC_MAP) == 0:
+        HTTPCORE_EXC_MAP = _load_httpcore_exceptions()
     try:
         yield
     except Exception as exc:
@@ -90,24 +118,6 @@ def map_httpcore_exceptions() -> typing.Iterator[None]:
         raise mapped_exc(message) from exc
 
 
-HTTPCORE_EXC_MAP = {
-    httpcore.TimeoutException: TimeoutException,
-    httpcore.ConnectTimeout: ConnectTimeout,
-    httpcore.ReadTimeout: ReadTimeout,
-    httpcore.WriteTimeout: WriteTimeout,
-    httpcore.PoolTimeout: PoolTimeout,
-    httpcore.NetworkError: NetworkError,
-    httpcore.ConnectError: ConnectError,
-    httpcore.ReadError: ReadError,
-    httpcore.WriteError: WriteError,
-    httpcore.ProxyError: ProxyError,
-    httpcore.UnsupportedProtocol: UnsupportedProtocol,
-    httpcore.ProtocolError: ProtocolError,
-    httpcore.LocalProtocolError: LocalProtocolError,
-    httpcore.RemoteProtocolError: RemoteProtocolError,
-}
-
-
 class ResponseStream(SyncByteStream):
     def __init__(self, httpcore_stream: typing.Iterable[bytes]) -> None:
         self._httpcore_stream = httpcore_stream
@@ -138,6 +148,8 @@ class HTTPTransport(BaseTransport):
         verify: typing.Any = None,
         cert: typing.Any = None,
     ) -> None:
+        import httpcore
+
         proxy = Proxy(url=proxy) if isinstance(proxy, (str, URL)) else proxy
         if verify is not None or cert is not None:  # pragma: nocover
             # Deprecated...
@@ -225,6 +237,7 @@ class HTTPTransport(BaseTransport):
         request: Request,
     ) -> Response:
         assert isinstance(request.stream, SyncByteStream)
+        import httpcore
 
         req = httpcore.Request(
             method=request.method,
@@ -284,6 +297,8 @@ class AsyncHTTPTransport(AsyncBaseTransport):
         verify: typing.Any = None,
         cert: typing.Any = None,
     ) -> None:
+        import httpcore
+
         proxy = Proxy(url=proxy) if isinstance(proxy, (str, URL)) else proxy
         if verify is not None or cert is not None:  # pragma: nocover
             # Deprecated...
@@ -371,6 +386,7 @@ class AsyncHTTPTransport(AsyncBaseTransport):
         request: Request,
     ) -> Response:
         assert isinstance(request.stream, AsyncByteStream)
+        import httpcore
 
         req = httpcore.Request(
             method=request.method,

Test output

show
F
=================================== FAILURES ===================================
___________________________________ test_get ___________________________________

server = <tests.conftest.TestServer object at 0x1032eba10>

    def test_get(server):
>       response = httpx.get(server.url)

tests/test_api.py:9: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
httpx/_api.py:204: in get
    return request(
httpx/_api.py:101: in request
    with Client(
httpx/_client.py:661: in __init__
    self._transport = self._init_transport(
httpx/_client.py:709: in _init_transport
    return HTTPTransport(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <httpx.HTTPTransport object at 0x103486120>, ssl_context = None
http1 = True, http2 = False
limits = Limits(max_connections=100, max_keepalive_connections=20, keepalive_expiry=5.0)
proxy = None, uds = None, local_address = None, retries = 0
socket_options = None, verify = None, cert = None

    def __init__(
        self,
        ssl_context: ssl.SSLContext | None = None,
        http1: bool = True,
        http2: bool = False,
        limits: Limits = DEFAULT_LIMITS,
        proxy: ProxyTypes | None = None,
        uds: str | None = None,
        local_address: str | None = None,
        retries: int = 0,
        socket_options: typing.Iterable[SOCKET_OPTION] | None = None,
        # Deprecated...
        verify: typing.Any = None,
        cert: typing.Any = None,
    ) -> None:
>       import httpcore
E       ModuleNotFoundError: No module named 'httpcore'

httpx/_transports/default.py:151: ModuleNotFoundError
---------------------------- Captured stderr setup -----------------------------
INFO:     Started server process [41171]
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
--------------------------- Captured stderr teardown ---------------------------
INFO:     Shutting down
INFO:     Finished server process [41171]
!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!!
1 failed in 0.25s