Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions httpcore/_api.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
from contextlib import contextmanager
from typing import Iterator, Optional, Union
from typing import Any, Dict, Iterator, Optional, Union

from ._models import URL, Response
from ._sync.connection_pool import ConnectionPool
from ._types import HeadersAsMapping, HeadersAsSequence


def request(
method: Union[bytes, str],
url: Union[URL, bytes, str],
*,
headers: Union[dict, list, None] = None,
headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None,
content: Union[bytes, Iterator[bytes], None] = None,
extensions: Optional[dict] = None,
extensions: Optional[Dict[str, Any]] = None,
) -> Response:
"""
Sends an HTTP request, returning the response.
Expand Down Expand Up @@ -50,9 +51,9 @@ def stream(
method: Union[bytes, str],
url: Union[URL, bytes, str],
*,
headers: Union[dict, list, None] = None,
headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None,
content: Union[bytes, Iterator[bytes], None] = None,
extensions: Optional[dict] = None,
extensions: Optional[Dict[str, Any]] = None,
) -> Iterator[Response]:
"""
Sends an HTTP request, returning the response within a content manager.
Expand Down
8 changes: 4 additions & 4 deletions httpcore/_async/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
from .http2 import AsyncHTTP2Connection
except ImportError: # pragma: nocover

class AsyncHTTP2Connection: # type: ignore
def __init__(self, *args, **kwargs) -> None: # type: ignore
class AsyncHTTP2Connection: # type: ignore[no-redef]
def __init__(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def]
raise RuntimeError(
"Attempted to use http2 support, but the `h2` package is not "
"installed. Use 'pip install httpcore[http2]'."
Expand All @@ -20,8 +20,8 @@ def __init__(self, *args, **kwargs) -> None: # type: ignore
from .socks_proxy import AsyncSOCKSProxy
except ImportError: # pragma: nocover

class AsyncSOCKSProxy: # type: ignore
def __init__(self, *args, **kwargs) -> None: # type: ignore
class AsyncSOCKSProxy: # type: ignore[no-redef]
def __init__(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def]
raise RuntimeError(
"Attempted to use SOCKS support, but the `socksio` package is not "
"installed. Use 'pip install httpcore[socks]'."
Expand Down
2 changes: 1 addition & 1 deletion httpcore/_async/connection_pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,6 @@ async def __aiter__(self) -> AsyncIterator[bytes]:
async def aclose(self) -> None:
try:
if hasattr(self._stream, "aclose"):
await self._stream.aclose() # type: ignore
await self._stream.aclose() # type: ignore[attr-defined]
finally:
await self._pool.response_closed(self._status)
17 changes: 11 additions & 6 deletions httpcore/_async/http2.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,9 @@ async def _read_incoming_data(
self._connection_error = True
raise exc

events = self._h2_state.receive_data(data)

events = typing.cast(
typing.List[h2.events.Event], self._h2_state.receive_data(data)
)
return events

async def _write_outgoing_data(self, request: Request) -> None:
Expand Down Expand Up @@ -381,13 +382,17 @@ async def _wait_for_outgoing_flow(self, request: Request, stream_id: int) -> int
WindowUpdated frames have increased the flow rate.
https://tools.ietf.org/html/rfc7540#section-6.9
"""
local_flow = self._h2_state.local_flow_control_window(stream_id)
max_frame_size = self._h2_state.max_outbound_frame_size
local_flow = typing.cast(
int, self._h2_state.local_flow_control_window(stream_id)
)
max_frame_size = typing.cast(int, self._h2_state.max_outbound_frame_size)
flow = min(local_flow, max_frame_size)
while flow == 0:
await self._receive_events(request)
local_flow = self._h2_state.local_flow_control_window(stream_id)
max_frame_size = self._h2_state.max_outbound_frame_size
local_flow = typing.cast(
int, self._h2_state.local_flow_control_window(stream_id)
)
max_frame_size = typing.cast(int, self._h2_state.max_outbound_frame_size)
flow = min(local_flow, max_frame_size)
return flow

Expand Down
6 changes: 2 additions & 4 deletions httpcore/_async/http_proxy.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ssl
from base64 import b64encode
from typing import List, Mapping, Optional, Sequence, Tuple, Union
from typing import List, Optional, Sequence, Tuple, Union

from .._exceptions import ProxyError
from .._models import (
Expand All @@ -15,15 +15,13 @@
from .._ssl import default_ssl_context
from .._synchronization import AsyncLock
from .._trace import Trace
from .._types import HeadersAsMapping, HeadersAsSequence
from ..backends.base import AsyncNetworkBackend
from .connection import AsyncHTTPConnection
from .connection_pool import AsyncConnectionPool
from .http11 import AsyncHTTP11Connection
from .interfaces import AsyncConnectionInterface

HeadersAsSequence = Sequence[Tuple[Union[bytes, str], Union[bytes, str]]]
HeadersAsMapping = Mapping[Union[bytes, str], Union[bytes, str]]


def merge_headers(
default_headers: Optional[Sequence[Tuple[bytes, bytes]]] = None,
Expand Down
13 changes: 7 additions & 6 deletions httpcore/_async/interfaces.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import AsyncIterator, Optional, Union
from typing import Any, AsyncIterator, Dict, Optional, Union

from .._compat import asynccontextmanager
from .._models import (
Expand All @@ -11,6 +11,7 @@
enforce_url,
include_request_headers,
)
from .._types import HeadersAsMapping, HeadersAsSequence


class AsyncRequestInterface:
Expand All @@ -19,9 +20,9 @@ async def request(
method: Union[bytes, str],
url: Union[URL, bytes, str],
*,
headers: Union[dict, list, None] = None,
headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None,
content: Union[bytes, AsyncIterator[bytes], None] = None,
extensions: Optional[dict] = None,
extensions: Optional[Dict[str, Any]] = None,
) -> Response:
# Strict type checking on our parameters.
method = enforce_bytes(method, name="method")
Expand All @@ -45,15 +46,15 @@ async def request(
await response.aclose()
return response

@asynccontextmanager
@asynccontextmanager # type: ignore[misc]
async def stream(
self,
method: Union[bytes, str],
url: Union[URL, bytes, str],
*,
headers: Union[dict, list, None] = None,
headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None,
content: Union[bytes, AsyncIterator[bytes], None] = None,
extensions: Optional[dict] = None,
extensions: Optional[Dict[str, Any]] = None,
) -> AsyncIterator[Response]:
# Strict type checking on our parameters.
method = enforce_bytes(method, name="method")
Expand Down
10 changes: 6 additions & 4 deletions httpcore/_compat.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# `contextlib.asynccontextmanager` exists from Python 3.7 onwards.
# For 3.6 we require the `async_generator` package for a backported version.
try:
from contextlib import asynccontextmanager # type: ignore
except ImportError:
from async_generator import asynccontextmanager # type: ignore # noqa
import sys

if sys.version_info >= (3, 7):
from contextlib import asynccontextmanager as asynccontextmanager
else:
from async_generator import asynccontextmanager as asynccontextmanager # noqa: F401
6 changes: 4 additions & 2 deletions httpcore/_exceptions.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import contextlib
from typing import Dict, Iterator, Type
from typing import Iterator, Mapping, Type

ExceptionMappingType = Mapping[Type[Exception], Type[Exception]]


@contextlib.contextmanager
def map_exceptions(map: Dict[Type, Type]) -> Iterator[None]:
def map_exceptions(map: ExceptionMappingType) -> Iterator[None]:
try:
yield
except Exception as exc: # noqa: PIE786
Expand Down
21 changes: 10 additions & 11 deletions httpcore/_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Any,
AsyncIterable,
AsyncIterator,
Dict,
Iterable,
Iterator,
List,
Expand All @@ -13,11 +14,9 @@
)
from urllib.parse import urlparse

# Functions for typechecking...

from ._types import HeadersAsMapping, HeadersAsSequence

HeadersAsSequence = Sequence[Tuple[Union[bytes, str], Union[bytes, str]]]
HeadersAsMapping = Mapping[Union[bytes, str], Union[bytes, str]]
# Functions for typechecking...


def enforce_bytes(value: Union[bytes, str], *, name: str) -> bytes:
Expand Down Expand Up @@ -318,9 +317,9 @@ def __init__(
method: Union[bytes, str],
url: Union[URL, bytes, str],
*,
headers: Union[dict, list, None] = None,
headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None,
content: Union[bytes, Iterable[bytes], AsyncIterable[bytes], None] = None,
extensions: Optional[dict] = None,
extensions: Optional[Dict[str, Any]] = None,
) -> None:
"""
Parameters:
Expand Down Expand Up @@ -356,9 +355,9 @@ def __init__(
self,
status: int,
*,
headers: Union[dict, list, None] = None,
headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None,
content: Union[bytes, Iterable[bytes], AsyncIterable[bytes], None] = None,
extensions: Optional[dict] = None,
extensions: Optional[Dict[str, Any]] = None,
) -> None:
"""
Parameters:
Expand All @@ -376,7 +375,7 @@ def __init__(
self.stream: Union[Iterable[bytes], AsyncIterable[bytes]] = enforce_stream(
content, name="content"
)
self.extensions: dict = {} if extensions is None else extensions
self.extensions: Dict[str, Any] = {} if extensions is None else extensions

self._stream_consumed = False

Expand Down Expand Up @@ -432,7 +431,7 @@ def close(self) -> None:
"You should use 'await response.aclose()' instead."
)
if hasattr(self.stream, "close"):
self.stream.close() # type: ignore
self.stream.close() # type: ignore[attr-defined]

# Async interface...

Expand Down Expand Up @@ -471,4 +470,4 @@ async def aclose(self) -> None:
"You should use 'response.close()' instead."
)
if hasattr(self.stream, "aclose"):
await self.stream.aclose() # type: ignore
await self.stream.aclose() # type: ignore[attr-defined]
2 changes: 1 addition & 1 deletion httpcore/_ssl.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ssl

import certifi # type: ignore
import certifi


def default_ssl_context() -> ssl.SSLContext:
Expand Down
8 changes: 4 additions & 4 deletions httpcore/_sync/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
from .http2 import HTTP2Connection
except ImportError: # pragma: nocover

class HTTP2Connection: # type: ignore
def __init__(self, *args, **kwargs) -> None: # type: ignore
class HTTP2Connection: # type: ignore[no-redef]
def __init__(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def]
raise RuntimeError(
"Attempted to use http2 support, but the `h2` package is not "
"installed. Use 'pip install httpcore[http2]'."
Expand All @@ -20,8 +20,8 @@ def __init__(self, *args, **kwargs) -> None: # type: ignore
from .socks_proxy import SOCKSProxy
except ImportError: # pragma: nocover

class SOCKSProxy: # type: ignore
def __init__(self, *args, **kwargs) -> None: # type: ignore
class SOCKSProxy: # type: ignore[no-redef]
def __init__(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def]
raise RuntimeError(
"Attempted to use SOCKS support, but the `socksio` package is not "
"installed. Use 'pip install httpcore[socks]'."
Expand Down
2 changes: 1 addition & 1 deletion httpcore/_sync/connection_pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,6 @@ def __iter__(self) -> Iterator[bytes]:
def close(self) -> None:
try:
if hasattr(self._stream, "close"):
self._stream.close() # type: ignore
self._stream.close() # type: ignore[attr-defined]
finally:
self._pool.response_closed(self._status)
17 changes: 11 additions & 6 deletions httpcore/_sync/http2.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,9 @@ def _read_incoming_data(
self._connection_error = True
raise exc

events = self._h2_state.receive_data(data)

events = typing.cast(
typing.List[h2.events.Event], self._h2_state.receive_data(data)
)
return events

def _write_outgoing_data(self, request: Request) -> None:
Expand Down Expand Up @@ -381,13 +382,17 @@ def _wait_for_outgoing_flow(self, request: Request, stream_id: int) -> int:
WindowUpdated frames have increased the flow rate.
https://tools.ietf.org/html/rfc7540#section-6.9
"""
local_flow = self._h2_state.local_flow_control_window(stream_id)
max_frame_size = self._h2_state.max_outbound_frame_size
local_flow = typing.cast(
int, self._h2_state.local_flow_control_window(stream_id)
)
max_frame_size = typing.cast(int, self._h2_state.max_outbound_frame_size)
flow = min(local_flow, max_frame_size)
while flow == 0:
self._receive_events(request)
local_flow = self._h2_state.local_flow_control_window(stream_id)
max_frame_size = self._h2_state.max_outbound_frame_size
local_flow = typing.cast(
int, self._h2_state.local_flow_control_window(stream_id)
)
max_frame_size = typing.cast(int, self._h2_state.max_outbound_frame_size)
flow = min(local_flow, max_frame_size)
return flow

Expand Down
6 changes: 2 additions & 4 deletions httpcore/_sync/http_proxy.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ssl
from base64 import b64encode
from typing import List, Mapping, Optional, Sequence, Tuple, Union
from typing import List, Optional, Sequence, Tuple, Union

from .._exceptions import ProxyError
from .._models import (
Expand All @@ -15,15 +15,13 @@
from .._ssl import default_ssl_context
from .._synchronization import Lock
from .._trace import Trace
from .._types import HeadersAsMapping, HeadersAsSequence
from ..backends.base import NetworkBackend
from .connection import HTTPConnection
from .connection_pool import ConnectionPool
from .http11 import HTTP11Connection
from .interfaces import ConnectionInterface

HeadersAsSequence = Sequence[Tuple[Union[bytes, str], Union[bytes, str]]]
HeadersAsMapping = Mapping[Union[bytes, str], Union[bytes, str]]


def merge_headers(
default_headers: Optional[Sequence[Tuple[bytes, bytes]]] = None,
Expand Down
Loading