Skip to content

Commit

Permalink
Move normalize header functions from _utils.py to _models.py (#3382)
Browse files Browse the repository at this point in the history
  • Loading branch information
AstralScribe authored Oct 30, 2024
1 parent 6622553 commit 83a8518
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 49 deletions.
52 changes: 30 additions & 22 deletions httpx/_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@
from ._urls import URL
from ._utils import (
is_known_encoding,
normalize_header_key,
normalize_header_value,
obfuscate_sensitive_headers,
parse_content_type_charset,
parse_header_links,
Expand All @@ -56,6 +54,24 @@
__all__ = ["Cookies", "Headers", "Request", "Response"]


def _normalize_header_key(key: str | bytes, encoding: str | None = None) -> bytes:
"""
Coerce str/bytes into a strictly byte-wise HTTP header key.
"""
return key if isinstance(key, bytes) else key.encode(encoding or "ascii")


def _normalize_header_value(value: str | bytes, encoding: str | None = None) -> bytes:
"""
Coerce str/bytes into a strictly byte-wise HTTP header value.
"""
if isinstance(value, bytes):
return value
if not isinstance(value, str):
raise TypeError(f"Header value must be str or bytes, not {type(value)}")
return value.encode(encoding or "ascii")


class Headers(typing.MutableMapping[str, str]):
"""
HTTP headers, as a case-insensitive multi-dict.
Expand All @@ -66,28 +82,20 @@ def __init__(
headers: HeaderTypes | None = None,
encoding: str | None = None,
) -> None:
if headers is None:
self._list = [] # type: typing.List[typing.Tuple[bytes, bytes, bytes]]
elif isinstance(headers, Headers):
self._list = [] # type: typing.List[typing.Tuple[bytes, bytes, bytes]]

if isinstance(headers, Headers):
self._list = list(headers._list)
elif isinstance(headers, Mapping):
self._list = [
(
normalize_header_key(k, lower=False, encoding=encoding),
normalize_header_key(k, lower=True, encoding=encoding),
normalize_header_value(v, encoding),
)
for k, v in headers.items()
]
else:
self._list = [
(
normalize_header_key(k, lower=False, encoding=encoding),
normalize_header_key(k, lower=True, encoding=encoding),
normalize_header_value(v, encoding),
)
for k, v in headers
]
for k, v in headers.items():
bytes_key = _normalize_header_key(k, encoding)
bytes_value = _normalize_header_value(v, encoding)
self._list.append((bytes_key, bytes_key.lower(), bytes_value))
elif headers is not None:
for k, v in headers:
bytes_key = _normalize_header_key(k, encoding)
bytes_value = _normalize_header_value(v, encoding)
self._list.append((bytes_key, bytes_key.lower(), bytes_value))

self._encoding = encoding

Expand Down
27 changes: 0 additions & 27 deletions httpx/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,33 +24,6 @@
)


def normalize_header_key(
value: str | bytes,
lower: bool,
encoding: str | None = None,
) -> bytes:
"""
Coerce str/bytes into a strictly byte-wise HTTP header key.
"""
if isinstance(value, bytes):
bytes_value = value
else:
bytes_value = value.encode(encoding or "ascii")

return bytes_value.lower() if lower else bytes_value


def normalize_header_value(value: str | bytes, encoding: str | None = None) -> bytes:
"""
Coerce str/bytes into a strictly byte-wise HTTP header value.
"""
if isinstance(value, bytes):
return value
if not isinstance(value, str):
raise TypeError(f"Header value must be str or bytes, not {type(value)}")
return value.encode(encoding or "ascii")


def primitive_value_to_str(value: PrimitiveData) -> str:
"""
Coerce a primitive data type into a string value.
Expand Down

0 comments on commit 83a8518

Please sign in to comment.