ResponseNotRead,
StreamConsumed,
)
-from ._status_codes import StatusCode
+from ._status_codes import codes
from ._types import (
CookieTypes,
HeaderTypes,
@property
def reason_phrase(self) -> str:
- return StatusCode.get_reason_phrase(self.status_code)
+ return codes.get_reason_phrase(self.status_code)
@property
def url(self) -> typing.Optional[URL]:
@property
def is_error(self) -> bool:
- return StatusCode.is_error(self.status_code)
+ return codes.is_error(self.status_code)
@property
def is_redirect(self) -> bool:
- return StatusCode.is_redirect(self.status_code) and "location" in self.headers
+ return codes.is_redirect(self.status_code) and "location" in self.headers
def raise_for_status(self) -> None:
"""
"For more information check: https://httpstatuses.com/{0.status_code}"
)
- if StatusCode.is_client_error(self.status_code):
+ if codes.is_client_error(self.status_code):
message = message.format(self, error_type="Client Error")
raise HTTPStatusError(message, response=self)
- elif StatusCode.is_server_error(self.status_code):
+ elif codes.is_server_error(self.status_code):
message = message.format(self, error_type="Server Error")
raise HTTPStatusError(message, response=self)
+import warnings
from enum import IntEnum
-class StatusCode(IntEnum):
+class codes(IntEnum):
"""HTTP status codes and reason phrases
Status codes from the following RFCs are all observed:
* RFC 7231: Hypertext Transfer Protocol (HTTP/1.1), obsoletes 2616
* RFC 7725: An HTTP Status Code to Report Legal Obstacles
"""
- def __new__(cls, value: int, phrase: str = "") -> "StatusCode":
+ def __new__(cls, value: int, phrase: str = "") -> "codes":
obj = int.__new__(cls, value) # type: ignore
obj._value_ = value
@classmethod
def get_reason_phrase(cls, value: int) -> str:
try:
- return StatusCode(value).phrase # type: ignore
+ return codes(value).phrase # type: ignore
except ValueError:
return ""
def is_redirect(cls, value: int) -> bool:
return value in (
# 301 (Cacheable redirect. Method may change to GET.)
- StatusCode.MOVED_PERMANENTLY,
+ codes.MOVED_PERMANENTLY,
# 302 (Uncacheable redirect. Method may change to GET.)
- StatusCode.FOUND,
+ codes.FOUND,
# 303 (Client should make a GET or HEAD request.)
- StatusCode.SEE_OTHER,
+ codes.SEE_OTHER,
# 307 (Equiv. 302, but retain method)
- StatusCode.TEMPORARY_REDIRECT,
+ codes.TEMPORARY_REDIRECT,
# 308 (Equiv. 301, but retain method)
- StatusCode.PERMANENT_REDIRECT,
+ codes.PERMANENT_REDIRECT,
)
@classmethod
NETWORK_AUTHENTICATION_REQUIRED = 511, "Network Authentication Required"
-codes = StatusCode
-
# Include lower-case styles for `requests` compatibility.
for code in codes:
setattr(codes, code._name_.lower(), int(code))
+
+
+class StatusCodeCompat:
+ def __call__(self, *args, **kwargs): # type: ignore
+ message = "`httpx.StatusCode` is deprecated. Use `httpx.codes` instead."
+ warnings.warn(message, DeprecationWarning)
+ return codes(*args, **kwargs)
+
+ def __getattr__(self, attr): # type: ignore
+ message = "`httpx.StatusCode` is deprecated. Use `httpx.codes` instead."
+ warnings.warn(message, DeprecationWarning)
+ return getattr(codes, attr)
+
+ def __getitem__(self, item): # type: ignore
+ message = "`httpx.StatusCode` is deprecated. Use `httpx.codes` instead."
+ warnings.warn(message, DeprecationWarning)
+ return codes[item]
+
+
+StatusCode = StatusCodeCompat()
+import pytest
+
import httpx
assert str(httpx.codes.NOT_FOUND) == "404"
+def test_status_code_value_lookup():
+ assert httpx.codes(404) == 404
+
+
+def test_status_code_phrase_lookup():
+ assert httpx.codes["NOT_FOUND"] == 404
+
+
def test_lowercase_status_code():
assert httpx.codes.not_found == 404 # type: ignore
def test_reason_phrase_for_unknown_status_code():
assert httpx.codes.get_reason_phrase(499) == ""
+
+
+def test_deprecated_status_code_class():
+ with pytest.warns(DeprecationWarning):
+ assert httpx.StatusCode.NOT_FOUND == 404
+
+ with pytest.warns(DeprecationWarning):
+ assert httpx.StatusCode(404) == 404
+
+ with pytest.warns(DeprecationWarning):
+ assert httpx.StatusCode["NOT_FOUND"] == 404